import { getAsset } from '@/api'
import { Anchor } from '@/utils/optional'
import { Texture } from '@babylonjs/core'
import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera'
import { Engine } from '@babylonjs/core/Engines/engine'
import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial'
import { Color3, Vector3 } from '@babylonjs/core/Maths/math'
import { Mesh } from '@babylonjs/core/Meshes/mesh'
import { Scene } from '@babylonjs/core/scene'
import {
  AdvancedDynamicTexture,
  Button,
  StackPanel,
  Vector2WithInfo,
  Image as GuiImage,
  TextBlock,
  Control
} from '@babylonjs/gui'
import { SetupContext } from 'vue'

interface SceneItem {
  name: string
  scene: Scene
  texture: AdvancedDynamicTexture
  tags: {
    [prop: string]: {
      icon?: GuiImage
      panel?: StackPanel
    }
  }
  anchors?: Anchor[]
}

const useViewer = (context: SetupContext) => {
  let currentScene: SceneItem
  const scenes: SceneItem[] = []

  const createTag = (anchor: Mesh) => {
    const tag = new StackPanel(anchor.name)

    tag.adaptHeightToChildren = true
    tag.adaptWidthToChildren = true

    // const btn = Button.CreateSimpleButton(anchor.name, anchor.name)
    const btn = new Button(anchor.name)
    btn.heightInPixels = 30
    // btn._automaticSize = true
    // btn. = true
    // btn.

    const titleText = new TextBlock(`${anchor.name}_title`, anchor.name)
    titleText.textWrapping = false
    titleText.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT

    // titleText.widthInPixels = 180
    titleText.heightInPixels = 30
    titleText.paddingBottomInPixels = 5
    titleText.paddingTopInPixels = 5
    titleText.paddingLeftInPixels = 5
    titleText.paddingRightInPixels = 5
    titleText.resizeToFit = true

    btn.addControl(titleText)
    btn.background = 'black'
    btn.alpha = 0.6
    btn.zIndex = 1
    btn.fontSize = 16

    btn.adaptHeightToChildren = true
    btn.adaptWidthToChildren = true
    // if (btn.textBlock) {
    //   btn.textBlock.widthInPixels = 150
    //   btn.textBlock.paddingBottomInPixels = 5
    //   btn.textBlock.paddingTopInPixels = 5
    //   btn.textBlock.paddingLeftInPixels = 5
    //   btn.textBlock.paddingRightInPixels = 5
    //   btn.textBlock.resizeToFit = true
    // }
    btn.color = 'white'
    btn.hoverCursor = 'pointer'

    btn.onPointerClickObservable.add((evt: Vector2WithInfo) => {
      if (evt.buttonIndex !== 0) return
      context.emit('trigged', anchor.name)
    })

    tag.addControl(btn)

    return tag
  }

  const addTag = (mesh: Mesh, si: SceneItem) => {
    const icon = new GuiImage(`${mesh.name}_icon`, '/assets/tag_dot.png')
    icon.width = '15px'
    icon.height = '15px'
    si.texture.addControl(icon)
    icon.linkWithMesh(mesh)

    const panel = createTag(mesh)
    si.texture.addControl(panel)
    panel.linkWithMesh(mesh)
    setTimeout(() => {
      console.log(panel)
      console.log(panel.widthInPixels)
      panel.linkOffsetX = panel.widthInPixels / 2 + 10
    }, 100)
    si.tags[mesh.name] = {
      icon,
      panel
    }
  }

  const switchScene = (name: string) => {
    const si = scenes.find((s) => s.name === name)
    if (!si || si === currentScene) return

    const cache = currentScene
    currentScene = si

    si.anchors &&
      si.anchors.forEach((anchor) => {
        const dot = Mesh.CreateSphere(anchor.name, 32, 1, si.scene)

        dot.position = new Vector3(
          anchor.position._x,
          anchor.position._y,
          anchor.position._z
        )

        addTag(dot, si)
      })

    cache && cache.texture.clear()
  }

  const load = async (id: string, creator: any, engine: Engine) => {
    const { data } = await getAsset(id)

    data.scenes.forEach((s) => {
      const scene = creator(s.name, s.asset)
      const { camera: c } = s
      const camera = <ArcRotateCamera>scene.activeCamera
      camera.setPosition(new Vector3(c._x, c._y, c._z))
      // render(scene, s.anchors)
      const tt = AdvancedDynamicTexture.CreateFullscreenUI('tags')

      const sceneItem: SceneItem = {
        name: s.name,
        scene: scene,
        texture: tt,
        tags: {},
        anchors: s.anchors
      }

      scenes.push(sceneItem)
    })

    engine.runRenderLoop(function () {
      const item = currentScene || scenes[0]
      item.scene.render()
    })

    switchScene(scenes[0].name)

    return {
      scenes,
      currentScene
    }
  }

  // const render = (scene: Scene, anchors: Anchor[]) => {

  // }

  const toggleAnchor = (name: string, bool: boolean) => {
    const c = currentScene || scenes[0]
    const mesh = c.scene.getMeshByName(name)
    mesh && mesh.setEnabled(bool)
    const tag = c.tags[name]
    if (!tag) return
    tag.icon && (tag.icon.isVisible = bool)
    tag.panel && (tag.panel.isVisible = bool)
  }

  return {
    load,
    toggleAnchor
  }
}

export default useViewer
